{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Collaboration and Competition\n",
    "\n",
    "---\n",
    "\n",
    "In this notebook, you will learn how to use the Unity ML-Agents environment for the third project of the [Deep Reinforcement Learning Nanodegree](https://www.udacity.com/course/deep-reinforcement-learning-nanodegree--nd893) program.\n",
    "\n",
    "### 1. Start the Environment\n",
    "\n",
    "We begin by importing the necessary packages.  If the code cell below returns an error, please revisit the project instructions to double-check that you have installed [Unity ML-Agents](https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Installation.md) and [NumPy](http://www.numpy.org/)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "import numpy as np\n",
    "import torch\n",
    "\n",
    "import sys\n",
    "import os\n",
    "\n",
    "sys.path.append(os.path.abspath('python/'))\n",
    "\n",
    "from unityagents import UnityEnvironment"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we will start the environment!  **_Before running the code cell below_**, change the `file_name` parameter to match the location of the Unity environment that you downloaded.\n",
    "\n",
    "- **Mac**: `\"path/to/Tennis.app\"`\n",
    "- **Windows** (x86): `\"path/to/Tennis_Windows_x86/Tennis.exe\"`\n",
    "- **Windows** (x86_64): `\"path/to/Tennis_Windows_x86_64/Tennis.exe\"`\n",
    "- **Linux** (x86): `\"path/to/Tennis_Linux/Tennis.x86\"`\n",
    "- **Linux** (x86_64): `\"path/to/Tennis_Linux/Tennis.x86_64\"`\n",
    "- **Linux** (x86, headless): `\"path/to/Tennis_Linux_NoVis/Tennis.x86\"`\n",
    "- **Linux** (x86_64, headless): `\"path/to/Tennis_Linux_NoVis/Tennis.x86_64\"`\n",
    "\n",
    "For instance, if you are using a Mac, then you downloaded `Tennis.app`.  If this file is in the same folder as the notebook, then the line below should appear as follows:\n",
    "```\n",
    "env = UnityEnvironment(file_name=\"Tennis.app\")\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:unityagents:\n",
      "'Academy' started successfully!\n",
      "Unity Academy name: Academy\n",
      "        Number of Brains: 1\n",
      "        Number of External Brains : 1\n",
      "        Lesson number : 0\n",
      "        Reset Parameters :\n",
      "\t\t\n",
      "Unity brain name: TennisBrain\n",
      "        Number of Visual Observations (per agent): 0\n",
      "        Vector Observation space type: continuous\n",
      "        Vector Observation space size (per agent): 8\n",
      "        Number of stacked Vector Observation: 3\n",
      "        Vector Action space type: continuous\n",
      "        Vector Action space size (per agent): 2\n",
      "        Vector Action descriptions: , \n"
     ]
    }
   ],
   "source": [
    "seed = 0\n",
    "torch.manual_seed(seed)\n",
    "random.seed(seed)\n",
    "np.random.seed(seed)\n",
    "env = UnityEnvironment(seed=seed, file_name=\"Tennis_Windows_x86_64/Tennis.app\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Environments contain **_brains_** which are responsible for deciding the actions of their associated agents. Here we check for the first brain available, and set it as the default brain we will be controlling from Python."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# get the default brain\n",
    "brain_name = env.brain_names[0]\n",
    "brain = env.brains[brain_name]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Examine the State and Action Spaces\n",
    "\n",
    "In this environment, two agents control rackets to bounce a ball over a net. If an agent hits the ball over the net, it receives a reward of +0.1.  If an agent lets a ball hit the ground or hits the ball out of bounds, it receives a reward of -0.01.  Thus, the goal of each agent is to keep the ball in play.\n",
    "\n",
    "The observation space consists of 8 variables corresponding to the position and velocity of the ball and racket. Two continuous actions are available, corresponding to movement toward (or away from) the net, and jumping. \n",
    "\n",
    "Run the code cell below to print some information about the environment."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of agents: 2\n",
      "Size of each action: 2\n",
      "There are 2 agents. Each observes a state with length: 24\n",
      "The state for the first agent looks like: [ 0.          0.          0.          0.          0.          0.\n",
      "  0.          0.          0.          0.          0.          0.\n",
      "  0.          0.          0.          0.         -6.65278625 -1.5\n",
      " -0.          0.          6.83172083  6.         -0.          0.        ]\n"
     ]
    }
   ],
   "source": [
    "# reset the environment\n",
    "env_info = env.reset(train_mode=True)[brain_name]\n",
    "\n",
    "# number of agents \n",
    "num_agents = len(env_info.agents)\n",
    "print('Number of agents:', num_agents)\n",
    "\n",
    "# size of each action\n",
    "action_size = brain.vector_action_space_size\n",
    "print('Size of each action:', action_size)\n",
    "\n",
    "# examine the state space \n",
    "states = env_info.vector_observations\n",
    "state_size = states.shape[1]\n",
    "print('There are {} agents. Each observes a state with length: {}'.format(states.shape[0], state_size))\n",
    "print('The state for the first agent looks like:', states[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Take Random Actions in the Environment\n",
    "\n",
    "In the next code cell, you will learn how to use the Python API to control the agents and receive feedback from the environment.\n",
    "\n",
    "Once this cell is executed, you will watch the agents' performance, if they select actions at random with each time step.  A window should pop up that allows you to observe the agents.\n",
    "\n",
    "Of course, as part of the project, you'll have to change the code so that the agents are able to use their experiences to gradually choose better actions when interacting with the environment!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Score (max over agents) from episode 1: 0.0\n",
      "Score (max over agents) from episode 2: 0.0\n",
      "Score (max over agents) from episode 3: 0.0\n",
      "Score (max over agents) from episode 4: 0.0\n",
      "Score (max over agents) from episode 5: 0.0\n"
     ]
    }
   ],
   "source": [
    "for i in range(1, 6):                                      # play game for 5 episodes\n",
    "    env_info = env.reset(train_mode=False)[brain_name]     # reset the environment    \n",
    "    states = env_info.vector_observations                  # get the current state (for each agent)\n",
    "    scores = np.zeros(num_agents)                          # initialize the score (for each agent)\n",
    "    \n",
    "    while True:\n",
    "        actions = np.random.randn(num_agents, action_size) # select an action (for each agent)\n",
    "        actions = np.clip(actions, -1, 1)                  # all actions between -1 and 1\n",
    "        env_info = env.step(actions)[brain_name]           # send all actions to tne environment\n",
    "        next_states = env_info.vector_observations         # get next state (for each agent)\n",
    "        rewards = env_info.rewards                         # get reward (for each agent)\n",
    "        dones = env_info.local_done                        # see if episode finished\n",
    "        scores += env_info.rewards                         # update the score (for each agent)\n",
    "        states = next_states                               # roll over states to next time step\n",
    "        \n",
    "        if np.any(dones):                                  # exit loop if episode finished\n",
    "            break\n",
    "    \n",
    "    print('Score (max over agents) from episode {}: {}'.format(i, np.max(scores)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. Train the Agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# MADDPG \n",
    "from maddpg_agent import maddpg_agent\n",
    "\n",
    "maddpg = maddpg_agent() "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Saves model weights to file\n",
    "def save_weights(dir):\n",
    "    for i in range(num_agents):\n",
    "        torch.save(maddpg.agents[i].actor_local.state_dict(),                     \n",
    "              os.path.join(dir, 'checkpoint_actor_{}.pth'.format(i)) )\n",
    "        torch.save(maddpg.agents[i].critic_local.state_dict(), \n",
    "              os.path.join(dir, 'checkpoint_critic_{}.pth'.format(i)) )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Episode: 20, Score: -0.0050, \tAverage Score: -0.0050, Time: 00:00:00 \n",
      "Episode: 40, Score: -0.0050, \tAverage Score: -0.0050, Time: 00:00:02 \n",
      "Episode: 60, Score: -0.0050, \tAverage Score: -0.0050, Time: 00:00:07 \n",
      "Episode: 80, Score: -0.0050, \tAverage Score: -0.0050, Time: 00:00:12 \n",
      "Episode: 100, Score: -0.0050, \tAverage Score: -0.0050, Time: 00:00:18 \n",
      "Episode: 120, Score: -0.0050, \tAverage Score: -0.0040, Time: 00:00:23 \n",
      "Episode: 140, Score: -0.0050, \tAverage Score: -0.0025, Time: 00:00:30 \n",
      "Episode: 160, Score: -0.0050, \tAverage Score: -0.0020, Time: 00:00:36 \n",
      "Episode: 180, Score: -0.0050, \tAverage Score: -0.0015, Time: 00:00:43 \n",
      "Episode: 200, Score: 0.0450, \tAverage Score: 0.0040, Time: 00:00:53 \n",
      "Episode: 220, Score: -0.0050, \tAverage Score: 0.0070, Time: 00:01:03 \n",
      "Episode: 240, Score: 0.0450, \tAverage Score: 0.0065, Time: 00:01:09 \n",
      "Episode: 260, Score: -0.0050, \tAverage Score: 0.0085, Time: 00:01:17 \n",
      "Episode: 280, Score: -0.0050, \tAverage Score: 0.0080, Time: 00:01:22 \n",
      "Episode: 300, Score: -0.0050, \tAverage Score: 0.0045, Time: 00:01:30 \n",
      "Episode: 320, Score: -0.0050, \tAverage Score: 0.0035, Time: 00:01:38 \n",
      "Episode: 340, Score: 0.0450, \tAverage Score: 0.0045, Time: 00:01:46 \n",
      "Episode: 360, Score: -0.0050, \tAverage Score: 0.0030, Time: 00:01:52 \n",
      "Episode: 380, Score: -0.0050, \tAverage Score: 0.0030, Time: 00:01:58 \n",
      "Episode: 400, Score: -0.0050, \tAverage Score: 0.0010, Time: 00:02:04 \n",
      "Episode: 420, Score: -0.0050, \tAverage Score: -0.0005, Time: 00:02:11 \n",
      "Episode: 440, Score: -0.0050, \tAverage Score: 0.0010, Time: 00:02:20 \n",
      "Episode: 460, Score: -0.0050, \tAverage Score: 0.0015, Time: 00:02:27 \n",
      "Episode: 480, Score: -0.0050, \tAverage Score: 0.0035, Time: 00:02:35 \n",
      "Episode: 500, Score: -0.0050, \tAverage Score: 0.0085, Time: 00:02:43 \n",
      "Episode: 520, Score: -0.0050, \tAverage Score: 0.0075, Time: 00:02:49 \n",
      "Episode: 540, Score: -0.0050, \tAverage Score: 0.0065, Time: 00:02:57 \n",
      "Episode: 560, Score: -0.0050, \tAverage Score: 0.0050, Time: 00:03:03 \n",
      "Episode: 580, Score: -0.0050, \tAverage Score: 0.0050, Time: 00:03:10 \n",
      "Episode: 600, Score: -0.0050, \tAverage Score: 0.0030, Time: 00:03:17 \n",
      "Episode: 620, Score: -0.0050, \tAverage Score: 0.0050, Time: 00:03:25 \n",
      "Episode: 640, Score: -0.0050, \tAverage Score: 0.0110, Time: 00:03:38 \n",
      "Episode: 660, Score: 0.0950, \tAverage Score: 0.0130, Time: 00:03:46 \n",
      "Episode: 680, Score: -0.0050, \tAverage Score: 0.0210, Time: 00:03:59 \n",
      "Episode: 700, Score: -0.0050, \tAverage Score: 0.0185, Time: 00:04:05 \n",
      "Episode: 720, Score: -0.0050, \tAverage Score: 0.0160, Time: 00:04:10 \n",
      "Episode: 740, Score: -0.0050, \tAverage Score: 0.0075, Time: 00:04:16 \n",
      "Episode: 760, Score: -0.0050, \tAverage Score: 0.0065, Time: 00:04:23 \n",
      "Episode: 780, Score: -0.0050, \tAverage Score: 0.0045, Time: 00:04:34 \n",
      "Episode: 800, Score: -0.0050, \tAverage Score: 0.0080, Time: 00:04:43 \n",
      "Episode: 820, Score: 0.0450, \tAverage Score: 0.0110, Time: 00:04:51 \n",
      "Episode: 840, Score: 0.1450, \tAverage Score: 0.0180, Time: 00:05:07 \n",
      "Episode: 860, Score: 0.0450, \tAverage Score: 0.0305, Time: 00:05:28 \n",
      "Episode: 880, Score: 0.0450, \tAverage Score: 0.0315, Time: 00:05:42 \n",
      "Episode: 900, Score: 0.0450, \tAverage Score: 0.0415, Time: 00:06:00 \n",
      "Episode: 920, Score: 0.0450, \tAverage Score: 0.0510, Time: 00:06:17 \n",
      "Episode: 940, Score: 0.0450, \tAverage Score: 0.0545, Time: 00:06:34 \n",
      "Episode: 960, Score: 0.1450, \tAverage Score: 0.0535, Time: 00:06:51 \n",
      "Episode: 980, Score: 0.0450, \tAverage Score: 0.0610, Time: 00:07:12 \n",
      "Episode: 1000, Score: 0.0450, \tAverage Score: 0.0615, Time: 00:07:28 \n",
      "Episode: 1020, Score: -0.0050, \tAverage Score: 0.0550, Time: 00:07:38 \n",
      "Episode: 1040, Score: 0.1450, \tAverage Score: 0.0510, Time: 00:07:48 \n",
      "Episode: 1060, Score: 0.0450, \tAverage Score: 0.0570, Time: 00:08:08 \n",
      "Episode: 1080, Score: 0.0450, \tAverage Score: 0.0565, Time: 00:08:25 \n",
      "Episode: 1100, Score: 0.0450, \tAverage Score: 0.0670, Time: 00:08:49 \n",
      "Episode: 1120, Score: 0.1450, \tAverage Score: 0.0865, Time: 00:09:15 \n",
      "Episode: 1140, Score: 0.0450, \tAverage Score: 0.1115, Time: 00:09:46 \n",
      "Episode: 1160, Score: 0.0450, \tAverage Score: 0.1170, Time: 00:10:11 \n",
      "Episode: 1180, Score: 0.2950, \tAverage Score: 0.1250, Time: 00:10:36 \n",
      "Episode: 1200, Score: -0.0050, \tAverage Score: 0.1160, Time: 00:10:53 \n",
      "Episode: 1220, Score: 2.3450, \tAverage Score: 0.1350, Time: 00:11:39 \n",
      "Episode: 1240, Score: 0.0450, \tAverage Score: 0.1660, Time: 00:12:38 \n",
      "Episode: 1260, Score: 0.1950, \tAverage Score: 0.2350, Time: 00:14:01 \n",
      "Episode: 1280, Score: 0.0450, \tAverage Score: 0.3336, Time: 00:15:56 \n",
      "Episode: 1300, Score: 0.0450, \tAverage Score: 0.4592, Time: 00:18:07 \n",
      "\n",
      "*** Environment solved in 1302 episodes!\tAverage Score: 0.51 ***\n",
      "\n",
      "Episode: 1320, Score: 0.0450, \tAverage Score: 0.5434, Time: 00:20:07 \n",
      "Episode: 1340, Score: 0.0450, \tAverage Score: 0.4999, Time: 00:20:30 \n",
      "Episode: 1360, Score: 0.0450, \tAverage Score: 0.5736, Time: 00:22:51 \n",
      "Episode: 1380, Score: 0.0450, \tAverage Score: 0.4900, Time: 00:23:33 \n",
      "Episode: 1400, Score: 0.0450, \tAverage Score: 0.3955, Time: 00:24:17 \n",
      "Episode: 1420, Score: 0.0450, \tAverage Score: 0.3785, Time: 00:25:51 \n",
      "Episode: 1440, Score: 2.6000, \tAverage Score: 0.6059, Time: 00:29:11 \n",
      "*** Episode 1450\tAverage Score: 0.55, Time: 00:29:18 ***\n",
      " \n",
      "Episode: 1460, Score: 1.8950, \tAverage Score: 0.5722, Time: 00:31:11 \n",
      "Episode: 1480, Score: 0.0450, \tAverage Score: 0.6788, Time: 00:33:26 \n",
      "Episode: 1500, Score: 0.7950, \tAverage Score: 0.9267, Time: 00:37:45 \n",
      "*** Episode 1500\tAverage Score: 0.93, Time: 00:37:45 ***\n",
      " \n",
      "Episode: 1520, Score: -0.0050, \tAverage Score: 0.9882, Time: 00:40:17 \n",
      "Episode: 1540, Score: 2.6000, \tAverage Score: 0.9486, Time: 00:43:17 \n",
      "*** Episode 1550\tAverage Score: 1.11, Time: 00:46:03 ***\n",
      " \n",
      "Episode: 1560, Score: 2.6500, \tAverage Score: 1.0685, Time: 00:47:36 \n",
      "Episode: 1580, Score: 2.6000, \tAverage Score: 1.1664, Time: 00:51:30 \n",
      "Episode: 1600, Score: 0.0450, \tAverage Score: 1.1409, Time: 00:55:57 \n",
      "*** Episode 1600\tAverage Score: 1.14, Time: 00:55:57 ***\n",
      " \n",
      "Episode: 1620, Score: 1.4950, \tAverage Score: 1.1379, Time: 00:58:45 \n",
      "Episode: 1640, Score: 0.0950, \tAverage Score: 1.1464, Time: 01:02:11 \n",
      "*** Episode 1650\tAverage Score: 1.16, Time: 01:05:03 ***\n",
      " \n",
      "Episode: 1660, Score: 0.0450, \tAverage Score: 1.2741, Time: 01:08:14 \n",
      "Episode: 1680, Score: 2.6000, \tAverage Score: 1.3547, Time: 01:13:11 \n",
      "Episode: 1700, Score: 0.0950, \tAverage Score: 1.4214, Time: 01:18:16 \n",
      "*** Episode 1700\tAverage Score: 1.42, Time: 01:18:16 ***\n",
      " \n"
     ]
    }
   ],
   "source": [
    "from collections import deque\n",
    "import time\n",
    "\n",
    "def train(maddpg, env, dir_chkpoints, n_episodes=1000, save_every=50):\n",
    "    \"\"\"Training loop helper for running the environment using the MADDPG algorithm.\n",
    "    Params\n",
    "    ======\n",
    "        maddpg: instance of maddpg_agent wrapper class\n",
    "        env (UnityEnvironment): instance of Unity environment for training\n",
    "        dir_chkpoints: directory to save model weights\n",
    "        n_episodes (int): number of episodes to train for\n",
    "        save_every (int): frequency to save model weights\n",
    "    \"\"\"\n",
    "    \n",
    "    solved = False\n",
    "    scores_total = []\n",
    "    scores_deque = deque(maxlen=100)\n",
    "    scores_global = []\n",
    "    best_score = 0.0\n",
    "    time_start = time.time()\n",
    "    \n",
    "    # Environment information\n",
    "    brain_name = env.brain_names[0]\n",
    "\n",
    "    # Used for learning period to update the model weights\n",
    "    global_step_number = 0\n",
    "    \n",
    "    for i_episode in range(1, n_episodes+1):\n",
    "        \n",
    "        env_info = env.reset(train_mode=True)[brain_name]\n",
    "        states = env_info.vector_observations\n",
    "                    \n",
    "        scores = np.zeros(num_agents)\n",
    "        maddpg.reset()\n",
    "\n",
    "        while True:\n",
    "            actions = maddpg.act(states)\n",
    "\n",
    "            env_info = env.step(actions)[brain_name]\n",
    "            next_states = env_info.vector_observations\n",
    "            rewards = env_info.rewards\n",
    "            dones = env_info.local_done\n",
    "            \n",
    "            global_step_number += 1\n",
    "            maddpg.step(states, actions, rewards, next_states, dones, global_step_number)\n",
    "\n",
    "            scores += rewards\n",
    "            states = next_states\n",
    "\n",
    "            if np.any(dones):\n",
    "                break\n",
    "        \n",
    "        mean_score = np.mean(scores) # mean on 2 agents\n",
    "        scores_total.append(mean_score)\n",
    "        scores_deque.append(mean_score) # mean on 2 agents for 100 episodes\n",
    "        score_average_100epis = np.mean(scores_deque) # value = mean on 100 episodes \n",
    "        scores_global.append(score_average_100epis) # \n",
    "        \n",
    "        print_every = 20\n",
    "        if i_episode % print_every == 0:\n",
    "            s = (int)(time.time() - time_start)\n",
    "            print('Episode: {}, Score: {:.4f}, \\tAverage Score: {:.4f}, Time: {:02}:{:02}:{:02} '\\\n",
    "                 .format(i_episode, mean_score,  score_average_100epis, s//3600, s%3600//60, s%60))\n",
    "\n",
    "        if score_average_100epis >= 0.5 and not solved:\n",
    "            print('\\n*** Environment solved in {:d} episodes!\\tAverage Score: {:.2f} ***\\n'.format(\n",
    "                i_episode, score_average_100epis))\n",
    "            solved = True\n",
    "            save_weights(dir_chkpoints)\n",
    "            best_score = score_average_100epis\n",
    "\n",
    "        if i_episode % save_every == 0 and solved:\n",
    "            # Only save these weights if they are better than the ones previously saved\n",
    "            if score_average_100epis > best_score:\n",
    "                best_score = score_average_100epis\n",
    "                save_weights(dir_chkpoints)\n",
    "                s = (int)(time.time() - time_start) \n",
    "                print('*** Episode {}\\tAverage Score: {:.2f}, Time: {:02}:{:02}:{:02} ***\\n '\\\n",
    "                     .format(i_episode, np.mean(scores_deque), s//3600, s%3600//60, s%60))  \n",
    "        \n",
    "\n",
    "    return scores_total, scores_global\n",
    "\n",
    "dir_chkpoints = 'dir_chk_1700d_episodes'\n",
    "scores_total, scores_global = train(maddpg, env, dir_chkpoints, n_episodes=1700)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5. Plot the  training results "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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78cee6wHVLYY3H333X3GjBkz9Omnn+6RmprqOWHChKioqKjYCRMmRO3fv98TYMaMGZG33HJL35EjR0ZHRETEvfPOO92hchGyMWPGDL300ksHRkZGDp87d26f1157LTguLi4mKioqtnqZ9ZMnT5qmTp06aPjw4THDhw+PWblypR/AX/7yl94zZ86MHDt27NCIiIi4p59+Ohzg3nvvjTh27JhXdHR07F133RVR+/2eOHHCIzg42OLj46MBevXqZYmMjKwA+OKLLwJiYmJio6KiYmfOnBlZWlpaJ0n55z//GTZ79uya+l566aWQm2++uS/AggULguPi4mKio6NjZ82a1b/6abwvvvhiSGRk5PAxY8YM3bRpU52H8rWUtIwIIYSLnTXdNL/7XV9SUtrc5F/H8OElvP12kw/gM5vNhujo6Njq7XvvvTf9jjvuyAUIDQ217N69e8+8efPC5s2b1+Pjjz8+cvHFF+d98MEHQX/605+yV69e7RcREVHet2/fBvOv8/LyjJs3b94HMGXKlMGzZs3K/sMf/pD9wgsvhMyZM6fvqlWrDgKcOnXKIykpae/27du9r7rqqsG33nprLsDevXt9li5deig8PNzSv3//OC8vr6ydO3fu+fvf/x4+f/788LfffvvYXXfd1fcvf/nLqalTpxbt37/fc+rUqUMOHTq0C+DAgQPemzZt2peXl2eMiYkZ/te//jVz/vz5x6dPn+5jryXo17/+dcEzzzzTOzIycvg555xTcP311+dcdtllRSUlJequu+4asHLlyn3x8fHmq666KvK5554Le+yxx05Xn3vjjTfmjh8/Pho4DrB06dLgRx55JH3r1q3eS5cuDU5KStrr5eWlf/vb3/Z7/fXXQy6//PKCefPm9d6yZcue4OBg68SJE4cOHz68wdOPHSXJiBCiSzlLbvuilqa6aWbNmpULMHbs2JIvv/yye9W+nKeeeqr3n/70p+wPPvggeMaMGTn2zq1+yi/Atm3b/L799tuDAHPmzMl58skna1oRrrjiijyj0cjo0aPLsrOza/pz4uLiivv3718B0K9fP/Mll1ySD5CQkFC6bt26AICNGzd2279/f80D5YqKioy5ubkGgIsvvjjPx8dH+/j4WIKDgyuOHz/e5D07MDDQlpKSsnv58uUB33//fcDNN9886LHHHjs+ZsyYkoiICHN8fLwZ4JZb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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "len of scores_total:  1700 \n",
      "len of score_global:  1700\n"
     ]
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "%matplotlib inline\n",
    "\n",
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111)\n",
    "\n",
    "plt.plot(np.arange(1, len(scores_total) + 1), scores_total, label=\"Max Score\")\n",
    "plt.plot(np.arange(1, len(scores_global) + 1), \n",
    "    scores_global, label=\"Avg on 100 episodes\") \n",
    "# This line indicates the score at which the environment is considered solved\n",
    "plt.axhline(y=0.5, color=\"r\",  label=\"Environment Solved\") \n",
    "\n",
    "plt.legend(bbox_to_anchor=(1.05, 1)) \n",
    "plt.ylabel(\"Score\")\n",
    "plt.xlabel(\"Episode # \")\n",
    "plt.show()\n",
    "\n",
    "print('len of scores_total: ', len(scores_total), '\\nlen of score_global: ',\\\n",
    "    len(scores_global))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "env.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
